#pragma once
//.hpp是把头文件和源文件合成一体，一般是写开源软件的
#include <iostream>
#include <unistd.h>

using namespace std;

typedef void(*work_t)(int);  //函数指针类型
typedef void(*task_t)(int, pid_t);  //函数指针类型

void PrintLog(int fd, pid_t pid)
{
    cout << "sub process: " << pid << ", fd: " << fd<< ", task is : printf log task\n" << endl;
}

void ReloadConf(int fd, pid_t pid)
{
    cout << "sub process: " << pid << ", fd: " << fd<< ", task is : reload conf task\n" << endl;
}

void ConnectMysql(int fd, pid_t pid)
{
    cout << "sub process: " << pid << ", fd: " << fd<< ", task is : connect mysql task\n" << endl;
}

task_t tasks[3] = {PrintLog, ReloadConf, ConnectMysql}; //任务数组

//随机选择任务码
uint32_t NextTask()
{
    return rand() % 3;
}

//子进程处理管道中的任务
void worker(int fd)
{
    while(true)
    {
        //command_code实际上是子进程任务tasks数组的下标
        uint32_t command_code = 0; //uint32_t：一个无符号的32位整型数据类型
        //管道文件以重定向，将从管道中读取到的数据存储在command_code变量中。
        //这里，子进程将会阻塞等待read中，直到父进程调用write开始往管道中写数据
        ssize_t n = read(0, &command_code, sizeof(command_code)); //ssize_t：一个有符号的整型数据类型
        if(n == sizeof(command_code)) //当读取到的实际字节数等于最大读取字节数时程序正常
        {
            if(command_code >= 3) continue; //tasks任务数组大小3，当读取到的任务指令大于等于3时表示读取到了错误任务
            tasks[command_code](fd, getpid()); //任务指令读取成功后执行相应任务
        }
        //此时表示已经读到了文件末尾，写端也不再写入了，可以退出该进程并杀死
        else if(n == 0)
        {
            cout << "sub process: " << getpid() << " quit now..." << endl;
            break;
        }
    }
}